<?xml version="1.0" encoding="UTF-8"?><d:tdl xmlns="http://www.w3.org/1999/xhtml" xmlns:b="http://www.backbase.com/2006/btl" xmlns:bb="http://www.backbase.com/2006/client"  xmlns:d="http://www.backbase.com/2006/tdl" >

	<d:namespace name="http://www.backbase.com/2006/btl">

		<d:uses element="focusableElement" src="../focus/focus.xml"/>
		<d:uses element="rangeFormField" src="../rangeFormField/rangeFormField.xml"/>
		<d:uses element="positionElement dimensionElement" src="../visualElement/visualElement.xml"/>

		<d:element name="spinnerBase" extends="b:rangeFormField b:positionElement b:dimensionElement b:focusableElement" abstract="true">
			

			<d:attribute name="value">
				
			</d:attribute>

			<d:attribute name="step" default="1">
				
			</d:attribute>

			<d:attribute name="decimals" default="0">
				
			</d:attribute>

			<d:attribute name="stringBefore">
				
			</d:attribute>

			<d:attribute name="stringAfter">
				
			</d:attribute>

			<d:property name="defaultValue">
				
			</d:property>

			<d:property name="value">
				
			</d:property>

			<d:constructor type="text/javascript"><![CDATA[
				if (!this.hasAttribute('value')){
					var sMinValue = this.getAttribute('min');
					this.setProperty('value', sMinValue);
					this.setProperty('defaultValue', sMinValue);
				}
				var me = this;
				this.__spinnerStopTimer = function spinnerStopTimer(){
							if( me.__timer){
								clearTimeout( me.__timer);
								me.__timer = null;
								var sNewValue = me.getProperty('value');
								if(me.__valueOnFocus != sNewValue){
									me.__valueOnFocus = sNewValue;
									bb.command.fireEvent(me, 'change', true, false);
								}
							}
							bb.document.removeEventListener('mousemove', arguments.callee, false);
						}
			]]></d:constructor>

			<d:method name="increaseValue">
				
				<d:argument name="continuous">
					
				</d:argument>
				<d:body type="text/javascript"><![CDATA[
					var sValue = this.getProperty('value');

					var fValue = parseFloat(sValue);
					if(!isNaN(fValue)){
						var newValue = fValue + parseFloat( this.getAttribute('step') );
						var iDecimals = parseInt(this.getAttribute('decimals'));
						newValue = newValue.toFixed(iDecimals);
						this.setProperty('value', newValue);
						if( continuous){
							var me = this;
							var bFirstStart = this.__timer ? false : true;
							this.__timer = setTimeout(function(){me.increaseValue(true)}, bFirstStart ? 1000 : 100);
							if( bFirstStart){
								bb.document.addEventListener('mouseup', this.__spinnerStopTimer, false);
							}
						}
					}
				]]></d:body>
			</d:method>

			<d:method name="decreaseValue">
				
				<d:argument name="continuous">
					
				</d:argument>
				<d:body type="text/javascript"><![CDATA[
					var sValue = this.getProperty('value');

					var fValue = parseFloat(sValue);

					if(!isNaN(fValue)){
						var newValue = fValue - parseFloat( this.getAttribute('step') );
						var iDecimals = parseInt(this.getAttribute('decimals'));
						newValue = newValue.toFixed(iDecimals);
						this.setProperty('value', newValue);
						if( continuous){
							var me = this;
							var bFirstStart = this.__timer ? false : true;
							this.__timer = setTimeout(function(){me.decreaseValue(true)}, bFirstStart ? 1000 : 100);
							if( bFirstStart){
								bb.document.addEventListener('mouseup', this.__spinnerStopTimer, false);
							}
						}
					}
				]]></d:body>
			</d:method>

			<d:method name="formatValue">
				<!-- private method -->
				
				<d:argument name="value">
					
				</d:argument>
				<d:body type="text/javascript"><![CDATA[
					value = String(value);

					var sStringBefore = this.getAttribute('stringBefore');
					var sStringAfter = this.getAttribute('stringAfter');

					value = parseFloat(value);
					var iDecimals = parseInt(this.getAttribute('decimals'));
					value = value.toFixed(iDecimals);

					return sStringBefore + value + sStringAfter;
				]]></d:body>
			</d:method>

			<d:method name="unformatValue">
				<!-- private method -->
				
				<d:argument name="value">
					
				</d:argument>
				<d:body type="text/javascript"><![CDATA[
					value = String(value);

					var sStringBefore = this.getAttribute('stringBefore');
					var sStringAfter = this.getAttribute('stringAfter');
					// remove stringBefore from value
					if ( value.substr(0, sStringBefore.length) == sStringBefore )
						value = value.substr(sStringBefore.length);

					// remove stringAfter from value
					if ( value.substr(value.length - sStringAfter.length, value.length ) == sStringAfter )
						value = value.substring(0, value.length - sStringAfter.length);

					var iDecimals = parseInt(this.getAttribute('decimals'));
					/*
						Need to convert value to a string to prevent error in IE 5.5
					*/
					value = parseFloat("" + value);
					value = value.toFixed(iDecimals);

					/*
						Making sure this function returns a string. IE 5.5 does not accept setting
						the value of a form element to anything that is not string.
						'input.value = 6' will not work.
					*/
					return value + '';
				]]></d:body>
			</d:method>

			<d:method name="isCorrectValue">
				<!-- private method -->
				
				<d:argument name="value">
					
				</d:argument>
				<d:body type="text/javascript"><![CDATA[
					/*
						Need to convert value to a string to prevent error in IE 5.5
					*/
					var fValue = parseFloat("" + value);
					var fMin = parseFloat( this.getAttribute('min') );
					var fMax = parseFloat( this.getAttribute('max') );

					/*
						if it is a number, it is greater than or equal to the minimum value and
						it is lower than or equal to the maximum value, then it is a correct number.
					*/
					if(!isNaN(fValue)){
						if( fValue < fMin )
							fValue = fMin;
						else if( fValue > fMax )
							fValue = fMax;

					/*
						Need to convert return value to a string to prevent error in IE 5.5
					*/
						return "" + fValue
					}
					return false;
				]]></d:body>
			</d:method>

			<d:method name="handleChangeEvent">
				<!-- private method -->
				
				<d:body type="text/javascript"><![CDATA[
					var sValue = this.getProperty('value');

					sValue == this.unformatValue(sValue);

					var fValue = parseFloat(sValue);

					if(isNaN(fValue)){
						// if the value typed in is not a number, reset to previous value
						this.setProperty('value', this.getProperty('value'));
					} else {
						// first set new value
						this.setProperty('value', sValue);
					}
				]]></d:body>
			</d:method>

			<d:handler event="focus" type="text/javascript"><![CDATA[
				//store current value to compare on blur
				this.__valueOnFocus = this.getProperty('value');
			]]></d:handler>

			<d:handler event="blur" type="text/javascript"><![CDATA[
				// dispatch change event when value is not the same as when the element was focussed
				if ( this.__valueOnFocus != this.getProperty('value') )
					bb.command.fireEvent(this, 'change', true, false);
			]]></d:handler>

			<d:handler event="mousedown" match=".btl-spinner-upButton" type="text/javascript"><![CDATA[
				//prevent that input blurs, other elements that have focus will lose focus when forcing to focus the input
				event.preventDefault();

				//focus the input
				this.viewNode.getElementsByTagName('input')[0].focus();
				this.increaseValue( true);
			]]></d:handler>

			<d:handler event="mousedown" match=".btl-spinner-downButton" type="text/javascript"><![CDATA[
				//prevent that input blurs, other elements that have focus will lose focus when forcing to focus the input
				event.preventDefault();

				//focus the input
				this.viewNode.getElementsByTagName('input')[0].focus();
				this.decreaseValue( true);
			]]></d:handler>

			<d:handler event="mouseup" type="text/javascript"><![CDATA[
				clearTimeout( this.__timer);
				this.__timer = null;
				var sNewValue = this.getProperty('value');
				if(this.__valueOnFocus != sNewValue){
					this.__valueOnFocus = sNewValue;
					bb.command.fireEvent(this, 'change', true, false);
				}
			]]></d:handler>

			<d:handler event="mousewheel" type="application/javascript"><![CDATA[
				 if (event.target == this)
					if (!event.defaultPrevented) {
					 	if (event.wheelDelta > 0)
							this.decreaseValue();
					 	else
							this.increaseValue();
						event.preventDefault();
					}
			]]></d:handler>

			<d:handler event="keydown" type="text/javascript"><![CDATA[
				var iType = event.keyIdentifier == 'Up' ? 1 : ( event.keyIdentifier == 'Down' ? -1 : 0);
				if( iType != 0){
					if( iType > 0)
						this.increaseValue();
					else
						this.decreaseValue();
					event.preventDefault();
				}
			]]></d:handler>

			<d:handler event="keyup" type="text/javascript"><![CDATA[
				if(event.keyIdentifier == 'Up' || event.keyIdentifier == 'Down'){
					var sNewValue = this.getProperty('value');
					if(this.__valueOnFocus != sNewValue){
						this.__valueOnFocus = sNewValue;
						bb.command.fireEvent(this, 'change', true, false);
					}
				}
			]]></d:handler>

		</d:element>

	</d:namespace>
</d:tdl>